/**LRU缓存 - 最近最久未使用算法（淘汰最久没使用的）
 * @example
 *  const cache = new LRUCache<number, string>(3); // 创建一个容量为3的LRU缓存  
    cache.set(1, 'a');
    cache.set(2, 'b');
    cache.set(3, 'c');
    console.log('存放123后，数据按顺序存放', cache.map);
    console.log(cache.get(1)); // 'a'
    console.log('查看1后，1在最后面了', cache.map);
    cache.set(4, 'd'); // 缓存已满，需要淘汰最久未使用的数据（key=2）
    console.log('存放4后，2被删除，4在最后面了', cache.map);
    console.log(cache.get(2)); // undefined，因为key=2已被淘汰
    console.log('查看2后，2在最后面了', cache.map);
    console.log(cache.get(3)); // 'c'
    console.log('查看3后，3在最后面了', cache.map);
 */
export class LRUCache<Key, Value> {
    /**最大缓存容量 */
    maxSize: number
    /**缓存数据 - 思路：删除map最前面的数据，因为map是按插入顺序排序 */
    map = new Map<Key, Value>()
    constructor(maxSize: number) {
        this.maxSize = maxSize
    }
    /**获得缓存 */
    get(key: Key) {
        if (this.map.has(key)) {
            const data = this.map.get(key)!
            //先删除再存储，保证当前数据在map的最后边 （因为是最近最少使用算法，到时候会删除map最前面的数据）
            this.map.delete(key)
            this.map.set(key, data)
            return data
        }
    }
    /**设置缓存 */
    set(key: Key, value: Value) {
        //如果缓存中有，就要先删除，保证它是最新数据
        if (this.map.has(key)) {
            this.map.delete(key)
        }
        //如果缓存已经满了，删除最开头的那个
        else if (this.map.size >= this.maxSize) {
            const beDeteled = this.map.keys().next().value // 取出第一个元素 （ keys()返回一个迭代器 ）
            this.map.delete(beDeteled)
        }
        this.map.set(key, value)
    }
}
/**FIFO缓存 - 先进先出算法（淘汰最开始进入的）
 * - 不知道set是否会重置位置，看题目要求，如果会的话，在set操作里先删再增
 * @example
 *  const cache = new FIFOCache<number, string>(3); // 创建一个容量为3的LRU缓存  
    cache.set(1, 'a');
    cache.set(2, 'b');
    cache.set(3, 'c');
    console.log('存放123后，数据按顺序存放', cache.map);
    console.log(cache.get(1)); // 'a'
    console.log('查看1后，位置不变', cache.map);
    cache.set(4, 'd'); // 缓存已满，需要淘汰最久未使用的数据（key=2）
    console.log('存放4后，1被删除，4在最后面', cache.map);
    console.log(cache.get(1)); // undefined，因为key=1已被淘汰
    console.log('查看1后，位置不变', cache.map);
    console.log(cache.get(3)); // 'c'
    console.log('查看3后，位置不变', cache.map);
 */
export class FIFOCache<key, value>{
    /**最大缓存容量 */
    maxSize: number
    /**缓存数据 - 思路：删除map最前面的数据，因为map是按插入顺序排序 */
    map = new Map<key, value>()
    constructor(maxSize: number) {
        this.maxSize = maxSize
    }
    /**获得缓存 */
    get(key: key) {
        return this.map.get(key)
    }
    /**设置缓存 */
    set(key: key, value: value) {
        //如果缓存已经满了，删除最开头的那个
        if (this.map.size >= this.maxSize) {
            const beDeteled = this.map.keys().next().value // 取出第一个元素 （ keys()返回一个迭代器 ）
            this.map.delete(beDeteled)
        }
        this.map.set(key, value)
    }
}
/**LFU缓存 - 最近最少使用算法（淘汰访问频率最小的） TODO-用什么数据结构？ */
// export class LFUCache<key, value>{
//     /**最大缓存容量 */
//     maxSize: number
//     /**缓存数据 */
//     map = new Map<key, value>()
//     constructor(maxSize: number) {
//         this.maxSize = maxSize
//     }
// }